﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Mail;
using NVelocity;
using Castle.Core;
using MShop.Core ;
using System.Net.Mime;
using MShop.Core.Domain;
using MShop.Core.DataAccess;
using NVelocity.App;

namespace MShop.Core.Service.EmailSender
{
    public class DefaultEmailSender : MShop.Core.Service.EmailSender.IEmailSender
    {
        private readonly IShopContext _ShopContext;

        private readonly IEmailTemplateDao _EmailTemplateDao;

        private  System.Net.Mail.SmtpClient _SmtpClient;

        public event SendCompletedEventHandler SendCompleted;

        public DefaultEmailSender(IShopContext shopContext,IEmailTemplateDao emailTemplateDao)
        {
            _SmtpClient = new SmtpClient();
            _SmtpClient.SendCompleted += SendCompleted;
            _ShopContext = shopContext;
            _EmailTemplateDao = emailTemplateDao;
            Configure(_SmtpClient);
            
        }

        protected virtual void Configure(System.Net.Mail.SmtpClient smtpClient)
        {
            smtpClient.Port = _ShopContext.Settings.Port;
            smtpClient.Host = _ShopContext.Settings.SmtpServier;
            smtpClient.EnableSsl = _ShopContext.Settings.SSL;
            smtpClient.UseDefaultCredentials = true;
            smtpClient.Credentials = new System.Net.NetworkCredential(_ShopContext.Settings.Email, _ShopContext.Settings.Password);            
        }       

        public void Send(IEnumerable<MailMessage> messages)
        {
            foreach (var m in messages)
            {
                Send(m);
            }
        }

        public void Send(MailMessage message)
        { 
            _SmtpClient.Send(message);
        }

        public void Send(string from, string to, string subject, string messageText)
        {
            MailMessage message = new MailMessage(from, to, subject, messageText);
            _SmtpClient.Send(message);
        }

        public void SendAsync(MailMessage message,object userToken)
        {     
            _SmtpClient.SendAsync(message,userToken);
        }

        public void SendAsync(string from, string recipients, string subject, string body, Object userToken)
        {
            MailMessage message = new MailMessage(from, recipients, subject, body);
            _SmtpClient.SendAsync(message,userToken);
        }

        public void SendAsync(EmailEntity instance, object userToken)
        {
            EmailTemplate template = _EmailTemplateDao.GetByEmailEntity(instance.GetType());
            if (template != null)
            {
                string body = template.TemplateValues;
                string subject = template.Subject;

                instance.Created = DateTime.Now;
                if (string.IsNullOrEmpty(instance.SiteName))
                {
                    instance.SiteName = _ShopContext.Settings.WebSiteName;
                }
                if (string.IsNullOrEmpty(instance.SiteUrl))
                {
                    instance.SiteUrl = _ShopContext.Settings.WebSiteUrl;
                }

                /*Nvelocity Template Engine*/
                VelocityEngine vltEngine = new VelocityEngine();
                vltEngine.Init();


                NVelocity.Context.IContext context = new VelocityContext();
                System.Text.StringBuilder builder = new System.Text.StringBuilder();
                builder.Append(body);

                System.IO.StringWriter vltWriter = new System.IO.StringWriter();
                context.Put("Entity", instance);             
                vltEngine.Evaluate(context, vltWriter, null, builder.ToString());
                


                body=  vltWriter.ToString();
                System.IO.StringWriter vltWriter2 = new System.IO.StringWriter();
                builder.Clear();
                builder.Append(subject);
                vltEngine.Evaluate(context, vltWriter2, null, builder.ToString());
                subject = vltWriter2.ToString();

                MailMessage message = new MailMessage(_ShopContext.Settings.Email, instance.Email, subject, body);
                message.IsBodyHtml = true;
                message.Priority = (MailPriority)template.Priority;
                _SmtpClient.SendAsync(message, userToken);
            }
        }
    }
}